home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / kerberos / pc / krb_libd.lha / Lib / Des / DES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-23  |  10.9 KB  |  453 lines

  1. /*
  2.  * $Source: /mit/kerberos/src/lib/des/RCS/des.c,v $
  3.  * $Author: jtkohl $
  4.  *
  5.  * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
  6.  * of Technology.
  7.  *
  8.  * For copying and distribution information, please see the file
  9.  * <mit-copyright.h>.
  10.  *
  11.  * These routines perform encryption and decryption using the DES
  12.  * private key algorithm, or else a subset of it-- fewer inner loops.
  13.  * (AUTH_DES_ITER defaults to 16, may be less.)
  14.  *
  15.  * Under U.S. law, this software may not be exported outside the US
  16.  * without license from the U.S. Commerce department.
  17.  *
  18.  * The key schedule is passed as an arg, as well as the cleartext or
  19.  * ciphertext.
  20.  *
  21.  * All registers labeled imply Vax using the Ultrix or 4.2bsd
  22.  * compiler.
  23.  *
  24.  *
  25.  *    NOTE:  bit and byte numbering:
  26.  *            DES algorithm is defined in terms of bits of L
  27.  *            followed by bits of R.
  28.  *        bit 0  ==> lsb of L
  29.  *        bit 63 ==> msb of R
  30.  *
  31.  * Always work in register pairs, FROM L1,R1 TO L2,R2 to make
  32.  * bookkeeping easier.
  33.  *
  34.  * originally written by Steve Miller, MIT Project Athena
  35.  */
  36.  
  37. #include <mit_copy.h>
  38.  
  39. #include <stdio.h>
  40. #include <des.h>
  41. #include "des_intn.h"
  42. #include "s_table.h"
  43. #ifdef BIG
  44. #include "p_table.h"
  45. #endif
  46.  
  47. #ifdef DEBUG
  48. #define DBG_PRINT(s) if (des_debug & 2) \
  49.     des_debug_print(s,i,L1&0xffff,(L1>>16)&0xffff, \
  50.         R1&0xffff,(R1>>16)&0xffff)
  51. #else
  52. #define DBG_PRINT(s)
  53. #endif
  54.  
  55. extern int des_debug;
  56. extern des_cblock_print_file ();
  57.  
  58. int
  59. des_ecb_encrypt(clear, cipher, schedule, encrypt)
  60.     unsigned long *clear;
  61.     unsigned long *cipher;
  62.     int encrypt;        /* 0 ==> decrypt, else encrypt */
  63.     register des_key_schedule schedule; /* r11 */
  64. {
  65.  
  66.     /* better pass 8 bytes, length not checked here */
  67.  
  68.     register unsigned long R1, L1; /* R1 = r10, L1 = r9 */
  69.     register unsigned long R2, L2; /* R2 = r8, L2 = r7 */
  70.     long i;
  71.     /* one more registers left on VAX, see below P_temp_p */
  72. #ifdef BITS16
  73.     sbox_in_16_a S_in_16_a;
  74.     sbox_in_16_b S_in_16_b;
  75.     sbox_in_16_c S_in_16_c;
  76.     unsigned int  *S_in_a_16_p = (unsigned int *) &S_in_16_a;
  77.     unsigned int  *S_in_b_16_p = (unsigned int *) &S_in_16_b;
  78.     unsigned int  *S_in_c_16_p = (unsigned int *) &S_in_16_c;
  79. #endif
  80. #ifndef BITS32
  81. #ifndef BITS16
  82.     dunno how to do this machine type, you lose;
  83. #endif
  84. #endif
  85.     unsigned long P_temp;
  86.     register unsigned char  *P_temp_p = (unsigned char  *) & P_temp;
  87. #ifdef BITS16
  88.     sbox_out S_out;
  89.     unsigned long  *S_out_p = (unsigned long  *) &S_out;
  90. #endif
  91.     unsigned long R_save, L_save;
  92. #ifdef DEBUG
  93.     unsigned long dbg_tmp[2];
  94. #endif
  95.  
  96.     /*
  97.      * Use L1,R1 and L2,R2 as two sets of "64-bit" registers always
  98.      * work from L1,R1 input to L2,R2 output; initialize the cleartext
  99.      * into registers.
  100.      */
  101. #ifdef MUSTALIGN
  102. #ifdef DEBUG
  103.     /*
  104.      * If the alignment is wrong, the programmer really screwed up --
  105.      * we aren't even getting the right data type.  His problem.  Keep
  106.      * this code for debugging.
  107.      */
  108.     /* Make sure schedule is ok */
  109.     if ((long) schedule & 3) {
  110.     fprintf(stderr,"des.c schedule arg pointer not aligned\n");
  111.     abort();
  112.     }
  113. #endif
  114.     if ((long) clear & 3) {
  115.     bcopy((char *)clear++,(char *)&L_save,sizeof(L_save));
  116.     bcopy((char *)clear,(char *)&R_save,sizeof(R_save));
  117.     L1 = L_save;
  118.     R1 = R_save;
  119.     }
  120.     else
  121. #endif
  122.     {
  123.     if (clear) L1 = *clear++;
  124.     else L1 = NULL;
  125.     if (clear) R1 = *clear;
  126.     else R1 = NULL;
  127.     }
  128.  
  129. #ifdef DEBUG
  130.     if (des_debug & 2) {
  131.     printf("All values printed from low byte (bit 0)");
  132.     printf(" --> high byte (bit 63)\n");
  133.     i = 0;
  134.     dbg_tmp[0] = L1;
  135.     dbg_tmp[1] = R1;
  136.     printf("iter = %2d  before IP\n\t\tL1 R1 = ",i);
  137.     des_cblock_print_file (dbg_tmp, stdout);
  138.     }
  139.  
  140.     DBG_PRINT("before IP");
  141. #endif
  142.  
  143. /*   IP_start:*/
  144.  
  145.     /* all the Initial Permutation code is in the include file */
  146. #include "ip.c"
  147.     /* reset input to L1,R1 */
  148.     L1 = L2;
  149.     R1 = R2;
  150.  
  151.     /* iterate through the inner loop */
  152.     for (i = 0; i <= (AUTH_DES_ITER-1); i++) {
  153.  
  154. #ifdef DEBUG
  155.     if (des_debug & 2) {
  156.         dbg_tmp[0] = L1;
  157.         dbg_tmp[1] = R1;
  158.         printf("iter = %2d    start loop\n\t\tL1 R1 = ",i);
  159.         des_cblock_print_file (dbg_tmp, stdout);
  160.         DBG_PRINT("start loop");
  161.     }
  162.  
  163. #endif
  164.  
  165.     R_save = R1;
  166.     L_save = L1;
  167.  
  168. /*   E_start:*/
  169.     /* apply the E permutation from R1 to L2, R2 */
  170. #ifndef VAXASM
  171. #ifdef SLOW_E
  172. #include "e.c"
  173. #else /* Bill's fast E */
  174.     L2 = (R1 << 1);
  175.     if (R1 & (1UL<<31))
  176.         L2 |= 1UL<<0;
  177.     L2 &= 077;
  178.     L2 |= (R1 <<3) & 07700;
  179.     L2 |= (R1 <<5) & 0770000;
  180.     L2 |= (R1 <<7) & 077000000;
  181.     L2 |= (R1 <<9) & 07700000000;
  182.     L2 |= (R1 <<11) & 030000000000;
  183.  
  184.     /* now from right to right */
  185.  
  186.     R2 = ((R1 >> 17) & 0176000);
  187.     if (R1 & (1<<0)) R2 |= 1UL<<15;
  188.  
  189.     R2 |= ((R1 >> 21) & 017);
  190.     R2 |= ((R1 >> 19) & 01760);
  191. #endif /* SLOW_E */
  192. #else /* VAXASM */
  193.     /* E operations */
  194.     /* right to left */
  195.     asm("    rotl    $1,r10,r7");
  196.     L2 &= 077;
  197.     L2 |= (R1 <<3) & 07700;
  198.     L2 |= (R1 <<5) & 0770000;
  199.     L2 |= (R1 <<7) & 077000000;
  200.     L2 |= (R1 <<9) & 07700000000;
  201.     L2 |= (R1 <<11) & 030000000000;
  202.  
  203.     asm("    rotl    $-17,r10,r8");
  204.     R2 &= 0176000;
  205.     asm("    rotl    $-21,r10,r0");
  206.     asm("    bicl2    $-16,r0");
  207.     asm("  bisl2    r0,r8");
  208.     asm("    rotl    $-19,r10,r0");
  209.     asm("    bicl2    $-1009,r0");
  210.     asm("  bisl2    r0,r8");
  211.  
  212. #endif
  213.  
  214.     /* reset input to L1,R1 */
  215.     L1 = L2;
  216.     R1 = R2;
  217.  
  218. #ifdef DEBUG
  219.     if (des_debug & 2) {
  220.         dbg_tmp[0] = L1;
  221.         dbg_tmp[1] = R1;
  222.         DBG_PRINT("after e");
  223.         printf("iter = %2d    after e\n\t\tL1 R1 = ",i);
  224.         des_cblock_print_file (dbg_tmp, stdout);
  225.     }
  226. #endif
  227.  
  228. /*   XOR_start:*/
  229.     /*
  230.      * XOR with the key schedule, "schedule"
  231.      *
  232.      * If this is an encryption operation, use schedule[i],
  233.      * otherwise use schedule [AUTH_DES_ITER-i-1]
  234.      *
  235.      * First XOR left half.
  236.      */
  237.     if (encrypt) {
  238.         L1 ^= *(((unsigned long *) &schedule[i] )+0);
  239.         /* now right half */
  240.         R1 ^= *(((unsigned long *) &schedule[i] )+1);
  241.     }
  242.     else {
  243.         L1 ^= *(((unsigned long *) &schedule[AUTH_DES_ITER-i-1] )+0);
  244.         /* now right half */
  245.         R1 ^= *(((unsigned long *) &schedule[AUTH_DES_ITER-i-1] )+1);
  246.     }
  247.  
  248.     /* dont have to reset input to L1, R1 */
  249.  
  250. #ifdef DEBUG
  251.     if (des_debug & 2) {
  252.         dbg_tmp[0] = L1;
  253.         dbg_tmp[1] = R1;
  254.         DBG_PRINT("after xor");
  255.         printf("iter = %2d    after xor\n\t\tL1 R1 =",i);
  256.         des_cblock_print_file (dbg_tmp, stdout);
  257.     }
  258. #endif
  259.  
  260. /*   S_start:*/
  261.     /* apply the S selection from L1, R1 to R2 */
  262.  
  263. #ifdef notdef
  264. #include "s.c"
  265. #endif
  266.  
  267.     /* S operations , cant use registers for bit field stuff */
  268.     /* from S_in to S_out */
  269.  
  270. #ifdef BITS16
  271.     *S_in_a_16_p = L1&0xffff;
  272.     *S_in_b_16_p = (L1>>16)&0xffff;
  273.     *S_in_c_16_p = R1&0xffff;
  274.     (*(unsigned long *) &S_out) =
  275.         (unsigned) S_adj[0][S_in_16_a.b0];
  276.     S_out.b1 = (unsigned) S_adj[1][S_in_16_a.b1];
  277.     /* b2 spans two words */
  278.     S_out.b2 = (unsigned)
  279.         S_adj[2][(unsigned) S_in_16_a.b2
  280.              + (((unsigned) S_in_16_b.b2) << 4)];
  281.     S_out.b3 = (unsigned) S_adj[3][S_in_16_b.b3];
  282.     S_out.b4 = (unsigned) S_adj[4][S_in_16_b.b4];
  283.     /* b5 spans both parts */
  284.     S_out.b5 = (unsigned)
  285.         S_adj[5][(unsigned) S_in_16_b.b5
  286.              + (((unsigned) S_in_16_c.b5) << 2)];
  287.     S_out.b6 = (unsigned) S_adj[6][S_in_16_c.b6];
  288.     S_out.b7 = (unsigned) S_adj[7][S_in_16_c.b7];
  289.     R1 = *S_out_p;
  290. #else
  291.     /* is a 32 bit sys */
  292. #ifndef VAXASM
  293.     R2 =  (unsigned) S_adj[0][L1 & 077];
  294.     L2 = (unsigned) S_adj[1][(L1 >> 6) & 077];
  295.     R2 |= (L2 <<4 );
  296.     L2 = (unsigned) S_adj[2][(L1 >> 12) & 077];
  297.     R2 |= (L2 <<8);
  298.     L2 = (unsigned) S_adj[3][(L1 >> 18) & 077];
  299.     R2 |= (L2 <<12);
  300.     L2 = (unsigned) S_adj[4][(L1 >> 24) & 077];
  301.     R2 |= (L2 <<16);
  302.     /* b5 spans both parts */
  303.     L2 = (unsigned)
  304.         S_adj[5][(unsigned) ((L1 >>30) & 03) + ((R1 & 017) << 2)];
  305.     R2 |= (L2 << 20);
  306.     L2 = (unsigned) S_adj[6][(R1 >> 4) & 077];
  307.     R2 |= (L2 <<24);
  308.     L2 = (unsigned) S_adj[7][(R1 >> 10) & 077];
  309.     R1 = R2 | (L2 <<28);
  310.     /* reset input to L1, R1 */
  311. #else /* vaxasm */
  312.     /*
  313.      * this is the c code produced above, with
  314.      * extzv replaced by rotl
  315.      */
  316.     asm("bicl3    $-64,r9,r0");
  317.     asm("movzbl    _S_adj[r0],r8");
  318.     asm("rotl    $-6,r9,r0");
  319.     asm("bicl2    $-64,r0");
  320.     asm("movzbl    _S_adj+64[r0],r7");
  321.     asm("ashl    $4,r7,r0");
  322.     asm("bisl2    r0,r8");
  323.     asm("rotl    $-12,r9,r0");
  324.     asm("bicl2    $-64,r0");
  325.     asm("movzbl    _S_adj+128[r0],r7");
  326.     asm("ashl    $8,r7,r0");
  327.     asm("bisl2    r0,r8");
  328.     asm("rotl    $-18,r9,r0");
  329.     asm("bicl2    $-64,r0");
  330.     asm("movzbl    _S_adj+192[r0],r7");
  331.     asm("ashl    $12,r7,r0");
  332.     asm("bisl2    r0,r8");
  333.     asm("rotl    $-24,r9,r0");
  334.     asm("bicl2    $-64,r0");
  335.     asm("movzbl    _S_adj+256[r0],r7");
  336.     asm("ashl    $16,r7,r0");
  337.     asm("bisl2    r0,r8");
  338.     asm("rotl    $-30,r9,r0");
  339.     asm("bicl2    $-4,r0");
  340.     asm("bicl3    $-16,r10,r1");
  341.     asm("ashl    $2,r1,r1");
  342.     asm("addl2    r1,r0");
  343.     asm("movzbl    _S_adj+320[r0],r7");
  344.     asm("ashl    $20,r7,r0");
  345.     asm("bisl2    r0,r8");
  346.     asm("rotl    $-4,r10,r0");
  347.     asm("bicl2    $-64,r0");
  348.     asm("movzbl    _S_adj+384[r0],r7");
  349.     asm("ashl    $24,r7,r0");
  350.     asm("bisl2    r0,r8");
  351.     asm("rotl    $-10,r10,r0");
  352.     asm("bicl2    $-64,r0");
  353.     asm("movzbl    _S_adj+448[r0],r7");
  354.     asm("ashl    $28,r7,r0");
  355.     asm("bisl2    r8,r0");
  356.     asm("movl    r0,r10");
  357.  
  358. #endif /* vaxasm */
  359. #endif
  360.  
  361. #ifdef DEBUG
  362.     if (des_debug & 2) {
  363.         dbg_tmp[0] = L1;
  364.         dbg_tmp[1] = R1;
  365.         DBG_PRINT("after s");
  366.         printf("iter = %2d    after s\n\t\tL1 R1 = ",i);
  367.         des_cblock_print_file (dbg_tmp, stdout);
  368.     }
  369. #endif
  370.  
  371. /*   P_start:*/
  372.     /* and then the p permutation from R1 into R2 */
  373. #include "p.c"
  374.     /* reset the input to L1, R1 */
  375.     R1 = R2;
  376.  
  377. #ifdef DEBUG
  378.     if (des_debug & 2) {
  379.         dbg_tmp[0] = L1;
  380.         dbg_tmp[1] = R1;
  381.         DBG_PRINT("after p");
  382.         printf("iter = %2d    after p\n\t\tL1 R1 = ",i);
  383.         des_cblock_print_file (dbg_tmp, stdout);
  384.     }
  385. #endif
  386.  
  387.     /* R1 is the output value from the f() */
  388.     /* move R[iter] to L[iter+1] */
  389. /*   XOR_2_start:*/
  390.     L1 = R_save;
  391.     /* xor with left */
  392.     R1 = L_save ^ R1;
  393.     /* reset the input */
  394.     }
  395.  
  396.     /* flip left and right before final permutation */
  397.     L2 = R1;            /* flip */
  398.     R2 = L1;
  399.     /* reset the input */
  400.     L1 = L2;
  401.     R1 = R2;
  402.  
  403. #ifdef DEBUG
  404.     if (des_debug & 2) {
  405.     dbg_tmp[0] = L1;
  406.     dbg_tmp[1] = R1;
  407.     DBG_PRINT("before FP");
  408.     printf("iter = %2d  before FP\n\t\tL1 R1 = ",i);
  409.     des_cblock_print_file (dbg_tmp, stdout);
  410.     }
  411.  
  412. #endif
  413.  
  414. /*FP_start:*/
  415.     /* do the final permutation from L1R1 to L2R2 */
  416.     /* all the fp code is in the include file */
  417. #include "fp.c"
  418.  
  419.     /* copy the output to the ciphertext string;
  420.      * can be same as cleartext
  421.      */
  422.  
  423. #ifdef MUSTALIGN
  424.     if ((long) cipher & 3) {
  425.     L_save = L2;    /* cant bcopy a reg */
  426.     R_save = R2;
  427.     bcopy((char *)&L_save,(char *)cipher++,sizeof(L_save));
  428.     bcopy((char *)&R_save,(char *)cipher,sizeof(R_save));
  429.     }
  430.     else
  431. #endif
  432.     {
  433.     *cipher++ = L2;
  434.     *cipher = R2;
  435.     }
  436.  
  437. #ifdef DEBUG
  438.     if (des_debug & 2) {
  439.     L1 = L2;
  440.     R1 = R2;
  441.     dbg_tmp[0] = L1;
  442.     dbg_tmp[1] = R1;
  443.     DBG_PRINT("done");
  444.     printf("iter = %2d  done\n\t\tL1 R1 = ",i);
  445.     des_cblock_print_file (dbg_tmp, stdout);
  446.     }
  447. #endif
  448.  
  449.     /* that's it, no errors can be returned */
  450.     return 0;
  451. }
  452.  
  453.